using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;
using System.Threading;

namespace Tarea5
{
    abstract class ModelBase : ModelInterface
    {
        private List<ObserverInterface> observers = new List<ObserverInterface>();
        protected Thread modelThread;
        protected int size;
        protected int row;// jf
        protected int col;  // jf
        protected bool nextTurnIsCrossPlayerS;
        volatile protected int sleepInterval;
        volatile protected bool isPaused;
        volatile protected bool isStopped;
        volatile protected bool isRunning;

        virtual public void Initialize(int sleepInterval, int size, bool HumanMakesFirstMove)
        {
            this.nextTurnIsCrossPlayerS = true;
            this.size = size;
            this.sleepInterval = sleepInterval;
            this.isPaused = false;
            this.isStopped = false;
            this.isRunning = false;
            this.modelThread = new Thread(this.ModelStart);
        }

        /// <summary>
        /// Sleep this model algorithm's thread for as many miliseconds as SleepInterval property.
        /// </summary>
        virtual protected void Sleep()
        {
            if (isRunning)
                Thread.Sleep(this.SleepInterval);
        }

        /// <summary>
        /// Model algorithm thread entry point in non-interactive models.
        /// </summary>
        abstract protected void ModelStart();

        abstract public int SetPosition(int row, int col);

        abstract public int UndoLastMove();

        virtual public void Start()
        {
            isRunning = true;
            modelThread.Start();
        }

        virtual public void Pause()
        {
            if (isRunning)
            {
                if (isPaused == false)
                    modelThread.Suspend();
                else
                    modelThread.Resume();
                isPaused = !isPaused;
            }            
        }

        virtual public void Stop()
        {
            this.isRunning = false;
            this.isStopped = true;
        }


        public bool IsRunning
        {
            get { return isRunning; }
        }

        public bool IsStopped
        {
            get { return isStopped || modelThread.ThreadState == ThreadState.Stopped; }
        }

        public bool IsPaused
        {
            get { return isPaused; }
        }

        public int SleepInterval
        {
            get { return sleepInterval; }
            set { sleepInterval = value; }
        }

        public int Size
        {
            get { return size; }
        }

        public int Row
        {
            get { return row; }
        }

        public int Column
        {
            get { return col; }
        }

        public void NotifyAll(StateInterface state, string msg, string info)
        {
            foreach (ObserverInterface observer in observers)
            {
                observer.Update(state, msg, info);
            }
        }

        public void RegisterObserver(ObserverInterface o)
        {
            observers.Add(o);
        }

        public void RemoveObserver(ObserverInterface o)
        {
            observers.Remove(o);
        }

        public int MoveCell(int row, int col) { return 0; }
        public int UnDoMoveCell() { return 0; }

    }
}
